package cn.sc.collection;

import cn.sc.collection.base.CacheObject;
import cn.sc.AbstractSimpleCache;
import cn.sc.exceptions.CacheException;
import cn.sc.jedis.JedisClusterFactory;
import cn.sc.jedis.JedisFactory;
import cn.sc.jedis.RedisCommons;
import cn.sc.jedis.RedisSingleFactory;
import cn.sc.jedis.config.RedisInfo;
import cn.sc.jedis.serialization.DefaultSerialization;
import cn.sc.jedis.serialization.Serialization;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * @ClassName RedisSimpleCache
 * @Author 谢卓才
 * @Description redis存储方式
 * @Date 2022/11/13 9:17
 */
public class RedisSimpleCache<V> extends AbstractSimpleCache<V> {
    /**
     * key标识
     */
    protected final String prefix;

    /**
     * redis操作对象
     */
    protected final RedisCommons redisCommons;

    public RedisSimpleCache(String prefix){
        this(prefix,null);
    }

    public RedisSimpleCache(String prefix, Serialization serialization){
        if(!StringUtils.hasLength(prefix)){
            throw new CacheException("prefix is not null");
        }
        this.prefix = prefix;
        if(serialization == null){
            serialization = new DefaultSerialization();
        }
        JedisFactory jedisFactory = null;
        if(StringUtils.hasLength(RedisInfo.getGlobalRedisInfo().getCluster().getNodes())){
            jedisFactory = new JedisClusterFactory(serialization != null ? serialization : null);
        }
        if(jedisFactory == null){
            jedisFactory = new RedisSingleFactory(serialization != null ? serialization : null);
            if(jedisFactory == null){
                throw new CacheException("jedisFactory is not null");
            }
        }
        redisCommons = jedisFactory.create(RedisInfo.getGlobalRedisInfo());
    }


    @Override
    public List<CacheObject<V>> valueAll() {
        List<CacheObject<V>> result = this.redisCommons.hValues(prefix);
        return result == null ? new ArrayList<>(0) : result;
    }

    @Override
    public CacheObject<V> value(String key) {
        CacheObject<V> result = this.redisCommons.hGet(prefix, key);
        return result == null ? createNode(null,0) : result;
    }

    @Override
    public CacheObject<V> increase(String key, CacheObject<V> value) {
        CacheObject<V> result = this.redisCommons.hSet(prefix, key, value);
        return result == null ? createNode(null,0) : result;
    }

    @Override
    public void increase(Map<String, CacheObject<V>> values) {
        this.redisCommons.hmset(prefix,values);
    }

    @Override
    public Long cacheClear() {
        Long del = this.redisCommons.del(prefix);
        return del == null ? 0 : del;
    }

    @Override
    public Long delete(String key) {
        Long del = this.redisCommons.hDel(prefix,key);
        return del == null ? 0 : del;
    }

    @Override
    public Long delete(Set<String> keys) {
        Long del = this.redisCommons.hDel(prefix,keys.toArray(new String[0]));
        return del == null ? 0 : del;
    }


    @Override
    public void addCache(Map<String, V> come) {
        Map<String,CacheObject<V>> result = new HashMap<>();
        come.forEach((k,v)->{
            result.put(k,createNode(v,0));
        });
        increase(result);
    }

    /**
     * 获取所有的key
     */
    @Override
    public Set<String> protoKeys(){
        Set<String> result = this.redisCommons.hKeys(prefix);
        return result == null ? new HashSet<>(0) : result;
    }

    @Override
    public boolean isEmpty() {
        return size()==0L ? true : false;
    }

    @Override
    public Long size() {
        Long size = this.redisCommons.hSize(prefix);
        return size == null ? 0 : size;
    }

}
